package chloroform.json.comp

import scaladuct.PropertyValue
import chloroform.json.{JsonBuilderFactory, CookiePropertyProcessingContext, GenericFactoryForElement}
import chloroform.GatewayContext
import scaladuct.validation.ConstraintViolationException
import javax.validation.ConstraintViolation
import argo.jdom.JsonRootNode

/**
 * User: zslajchrt
 * Date: 16.5.11
 * Time: 20:32
 */
object Validation {
  def getConstructors =
    List(new CookieValidationConstructor)
}

class ValidationInfo extends JsonComposite {
  val isValid = boolean()
  val message = string()
}

class ValidationInfoHolder extends JsonComposite {
  val ValidationInfo = struct(new ValidationInfo())
}

class CookieValidationConstructor
  extends GenericFactoryForElement[PropertyValue[_], CookiePropertyProcessingContext, JsonBuilderFactory[JsonRootNode]] {

  def create(property: PropertyValue[_], ctx: CookiePropertyProcessingContext) = {
    val validationException: ConstraintViolationException =
      ctx.cookieGateway.asInstanceOf[GatewayContext].validationException

    if (validationException != null) {

      def findPropertyViolation(violation: ConstraintViolation[AnyRef]): Boolean = {
        val path = violation.getPropertyPath
        val iterator = path.iterator
        val pathBuilder = new StringBuilder()
        while (iterator.hasNext) {
          val node = iterator.next()

          if (!pathBuilder.isEmpty)
              pathBuilder.append('.')
          if (node.getName != null)
              pathBuilder.append(node.getName)

        }

        pathBuilder.toString() == property.name
      }

      validationException.violationSet.find(findPropertyViolation) match {
        case None => None
        case Some(violation) => {
          val validationInfoHolder = new ValidationInfoHolder()
          validationInfoHolder.ValidationInfo().isValid <= false
          validationInfoHolder.ValidationInfo().message <= violation.getMessage

          Some(validationInfoHolder)
        }
      }
    } else
      None
  }

}
